package com.newcapec.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Random;

/**
 * 3DESC加解密
 *
 * @author steven
 */
@Slf4j
public class ThreeDESUtils {

	// 定义加密算法
	private static final String Algorithm = "DESede";
	public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

	/**
	 * 加密
	 */
	public static String encryptMode(String key,String src) {
		try {
			return URLEncoder.encode(Base64.encodeBase64String(encryptMode(src.getBytes("utf-8"), key)), "UTF-8");
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 加密 src为源数据的字节数组
	 */
	public static byte[] encryptMode(byte[] src,String key) throws Exception {
		SecretKey deskey = new SecretKeySpec(build3Deskey(key), Algorithm);
		// 实例化cipher
		Cipher cipher = Cipher.getInstance(Algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, deskey);
		return cipher.doFinal(src);
	}


	/**
	 * 解密函数
	 */
	public static String decryptMode(String key,String src) {
		try {
			src = URLDecoder.decode(src,"UTF-8");
			return new String(decryptMode(Base64.decodeBase64(src),key),"utf-8");
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return null;
	}

	/**
  	 * 解密函数
	 */
	public static String decryptModeNoUrlDec(String key,String src) {
		try {
			return new String(decryptMode(Base64.decodeBase64(src),key),"utf-8");
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return null;
	}

	/**
	 * 解密函数
	 */
	public static byte[] decryptMode(byte[] src,String key) throws Exception {
		SecretKey deskey = new SecretKeySpec(build3Deskey(key), Algorithm);
		Cipher cipher = Cipher.getInstance(Algorithm);
		cipher.init(Cipher.DECRYPT_MODE, deskey);
		return cipher.doFinal(src);
	}

	/**
	 * 根据字符串生成密钥24位的字节数组
	 */
	public static byte[] build3Deskey(String keystr) throws Exception {
		byte[] key = new byte[24];
		byte[] temp = keystr.getBytes("utf-8");
		if (key.length > temp.length) {
			System.arraycopy(temp, 0, key, 0, temp.length);

		} else {
			System.arraycopy(temp, 0, key, 0, key.length);

		}
		return key;
	}

	/**
	 * 返回一个定长的带因子的固定的随机字符串(只包含大小写字母、数字)
	 * @param length 随机字符串长度
	 * @return 随机字符串
	 */
	public static String generateStringByKey(int length) {
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
		}
		return sb.toString();
	}
}
